
	/***********************************************************************************************

		Module: Jsl (native api)
		
		Methods:
			mod __ni_error_lineNumber	(e)																	- sid: 6.0
			mod __ni_error_charNumber	(e)																	- sid: 6.0
			mod __ni_error_scriptName	(e)																	- sid: 6.0
								
    	mod	__ni_stdout_debug			(msg)																- sid: 6.0
    	mod	__ni_stdout_info			(msg)																- sid: 6.0
    	mod	__ni_stdout_warn			(msg)																- sid: 6.0
    	mod	__ni_stdout_error			(msg)																- sid: 6.0
    	mod	__ni_stdout_log				(msg)																- sid: 6.0
		
			s		__ni_script_load			(url)																- sid: 6.0
			obj	__ni_script_execute		(script)														- sid: 6.0
		
			s		__ni_http_request			(url, params)												- sid: 3.0
			
			tid	__ni_timer_create			(action, interval*, n*)							- sid: 6.0
			b		__ni_timer_remove			(tid)																- sid: 6.0
					
      obj	__ni_error_capture		(e, cx*, args*)											- sid: 6.0
      		
		Private:
			obj __ni_stdout_header		()
			obj __ni_getParams				(s)
	     			
	************************************************************************************************/

	//@sys: global is not a property of [this] in v8cgi, this.global = undefined
	try 			{ jsl.__stype = !("version" in global.v8cgi) || "cli" }
	catch(e)	{}

	//@sys:	indirect call to remove the parameter passed by the native systems. The parameter
	//			is converted to string in a error stacktrace and it is dangerous because 
	//			can also not have the hasOwnProperty method and more (ex: web native event object)
	//-------------------------------------------------------------------------------
	jsl.__ni_boot = function(e) { if(jsl.__ready) jsl.__boot() }	
	//-------------------------------------------------------------------------------
	jsl.__ni_exit = function(e) { if(jsl.__ready) jsl.__exit() }		
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_header = function() {
		var time, h, m, ms
		
		time 	= new Date
		h			= time.getHours()						+ ""
		m			= time.getMinutes()					+ ""
		ms		= time.getMilliseconds()		+ ""
		
		h			= h.length 	=== 2 ? h 	: "0" 	+ h
		m			= m.length 	=== 2 ? m 	: "0" 	+ m
		ms		= ms.length === 3 ? ms 	: (ms.length === 2 ? "0" : "00") + ms
		
		return  "[" + h + ":" + m + ":" + ms + "]" 
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_getParams = function(s) {
		var search	= s && s.length ? decodeURIComponent(s).split("&") : []
		var params	= {}
		var id

		for(var a = 0; a < search.length; a++) {
			
			id = search[a].split("=")[0].replace(/\s+/g, "")
			
			if(id) 
				params[id] = search[a].split("=")[1] || "" 
		}
		
		return params
	}
		
	//1° - Web/Desktop system type			
	//-------------------------------------------------------------------------------
	if(!jsl.__stype) {
	
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_debug = function(msg) { 
		try {
			var print
			
			//@d[					
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]

			//@sys: Opera 11 				- navigator.vendor is null
			//@sys: Explorer 8 			- console.log/info/etc.. are typeof object, then we take an easy check 
			//@sys: Firefox 3.6.10 	- print = console.log -> error when print(msg) -> this.trace is not a function
			//												the method must be executed on the console object
			if(navigator.vendor && navigator.vendor.indexOf("Adobe") !== -1) 	print = parentSandboxBridge.trace
			if(this.__go.console && console.debug != null)										print = function(msg) { console.debug(msg) 	}	
			else if(this.__go.console && console.log != null)									print = function(msg) { console.log(msg)		}
							
			print && print(this.__ni_stdout_header() + "liquid(debug) >> "	+ msg)			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}		
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_info = function(msg) { 
		try {		
			var print
			
			//@d[					
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]

			//@sys: Opera 11 		- navigator.vendor is null
			//@sys: Explorer 8 	- console.log/info/etc.. are typeof object, then we take an easy check 
			if(navigator.vendor && navigator.vendor.indexOf("Adobe") !== -1) 	print = parentSandboxBridge.trace
			if(this.__go.console && console.info != null)											print = function(msg) { console.info(msg) }	
			else if(this.__go.console && console.log != null)									print = function(msg) { console.log(msg) 	}
							
			print && print(this.__ni_stdout_header() + "liquid(info)  >> "	+ msg)			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}			
	}	
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_warn = function(msg) { 
		try {			
			var print
			
			//@d[					
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]

			//@sys: Opera 11 		- navigator.vendor is null
			//@sys: Explorer 8 	- console.log/info/etc.. are typeof object, then we take an easy check 
			if(navigator.vendor && navigator.vendor.indexOf("Adobe") !== -1) 	print = parentSandboxBridge.trace
			if(this.__go.console && console.warn != null)											print = function(msg) { console.warn(msg) }	
			else if(this.__go.console && console.log != null)									print = function(msg) { console.log(msg)	}
							
			print && print(this.__ni_stdout_header() + "liquid(warn)  >> "	+ msg)			
			return msg + ""
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}			
	}	
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_error = function(msg) { 
		try {				
			var print
			
			//@d[					
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]

			//@sys: Opera 11 		- navigator.vendor is null
			//@sys: Explorer 8 	- console.log/info/etc.. are typeof object, then we take an easy check 
			if(navigator.vendor && navigator.vendor.indexOf("Adobe") !== -1) 	print = parentSandboxBridge.trace
			if(this.__go.console && console.error != null)										print = function(msg) { console.error(msg) 	}	
			else if(this.__go.console && console.log != null)									print = function(msg) { console.log(msg)		}
							
			print && print(this.__ni_stdout_header() + "liquid(error) >> "	+ msg)			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}	
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_log = function(msg) { 
		try {		
			//@d[					
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]
	
			//@sys: Opera 11 		- navigator.vendor is null
			//@sys: Explorer 8 	- console.log/info/etc.. are typeof object, then we take an easy check 
			if(navigator.vendor && navigator.vendor.indexOf("Adobe") !== -1) 	parentSandboxBridge.trace(msg)
			else if(this.__go.console && console.log != null)									console.log(msg) 			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}	
	//-------------------------------------------------------------------------------
	jsl.__ni_script_load = function(url) {
		try {
			var status, xhr, tid
			
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(url, "url")
			//@d]
			
			//@sys: Opera v.9.64 - multiple call to this method with same xhr throw an error 
			//			if last open has caused an error : INVALID_STATE_ERR
			//@sys: Explorer 8 - xhr is unreiable use activex. Vice versa strange and obscure behaviors
			if(window.ActiveXObject)				xhr = new ActiveXObject("MSXML2.XMLHTTP.3.0")
			else if(window.XMLHttpRequest) 	xhr = new XMLHttpRequest()
			else 														throw jsl.NativeError("NotSupported:XmlHttpRequest/ActiveX")
			
			tid = this.__ni_timer_create(function() {				
				var e 
				
				if(xhr.readyState < 4) {

					e 		= new jsl.Event
					e.url	= url + ""
				
					jsl.throwEvent("beforeLoadTimeOut", e) 
					xhr.abort()
					jsl.throwEvent("loadTimeOut", e)
				}
			}, this.__load_to, 1)
			
			try {
				xhr.open("GET", url, false)
				xhr.send("")	//@sys: Netscape/Flock - if null throw an error
			}
			catch(e) {
				this.__ni_timer_remove(tid)
				throw jsl.NativeError("LoadFailed", [ url, "(detail: " + e.message + ")" ])
			}

			//404 - we want also have the possibility to test if an url exists
			//@sys: Air 2 (and other..) - status code = 0 policy problem
			status = xhr.status
			if(!status)														throw jsl.NativeError("LoadFailed", [ url, "(security violation)"])
			if(status !== 404 && status !== 200)	throw jsl.NativeError("LoadFailed", [ url, "(code: " + xhr.status + ")" ])

			return status === 404 ? null : xhr.responseText
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_script_execute = function(script) {
		try {
			var node, tmp
			
			//@d[			
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(script, "s", "script")
			//@d]			
												
			if(!this.__debug) {
			
				if(!arguments.callee.__node) {
					//@sys: Firefox 3.6.13/ Explorer 8 - returns always a NodeList, never null 
					arguments.callee.__node = document.getElementsByTagName("head")[0] || document.getElementsByTagName("body")[0]
					if(!arguments.callee.__node)	throw jsl.NativeError("NullValue:HtmlHeadNode/HtmlBodyNode")
				}
				
				//0 syntax error, 1 error, 2 ok
				tmp					= this.__vars.tmp
				tmp.execute	= 0
				node 				= document.createElement("script")
				node.text 	= "try {\n" + script + "\n ;jsl.__vars.tmp.execute = 2 } catch(e) { jsl.__vars.tmp.execute = 1; jsl.__vars.error = e }"				
	
				arguments.callee.__node.appendChild(node)
				arguments.callee.__node.removeChild(node)
				
				if(!tmp.execute) 						throw jsl.ScriptError("BadScript", new SyntaxError)	
				else if(tmp.execute === 1)	throw jsl.ScriptError("BadScript", this.__vars.error)
			}
			else 				
				try 			{	this.__ni_script_execute.eval(script)	}
				catch(e) 	{	throw jsl.ScriptError("BadScript", e) }

			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	jsl.__ni_script_execute.eval = function(script) { return eval(script) }	
	//-------------------------------------------------------------------------------
	jsl.__ni_http_request = function(url, params) {
		try {
			var xhr, onChange, onComplete, onError, data, async, tid, pms, b, error
			
			//@d[
			if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()
			jsl.validate(url, "url")

			if(arguments.length === 2) {
				if(!jsl.isObject(params))					throw jsl.ParamError("BadType:params:object")
				if(params.__onComplete 	!= null)	jsl.validate(params.__onComplete, "f", "params.__onComplete")
				if(params.__onError 		!= null)	jsl.validate(params.__onError		, "f", "params.__onError")
			}
			//@d]
			
			pms					= params || {}
			onComplete 	= pms.__onComplete
			onError			= pms.__onError
			async				= !!onComplete
			data				= []
			
			//@sys: Opera v.9.64 - multiple call to this method with same xhr throw an error 
			//			if last open has caused an error : INVALID_STATE_ERR
			if(window.XMLHttpRequest) 		xhr = new XMLHttpRequest()
			else if(window.ActiveXObject)	xhr = new ActiveXObject("MSXML2.XMLHTTP.3.0")
			else 													throw jsl.NativeError("NotSupported:XmlHttpRequest/ActiveX")

			for(var a in pms)
				if(a !== "__onComplete" && a !== "__onError")
					data.push(encodeURIComponent(a) + "=" + encodeURIComponent(pms[a]))
									
			onChange = function() {
				try {
					var e, error
					
					if(xhr.readyState === 4) {

						jsl.__ni_timer_remove(tid)	
					
						if(xhr.status === 200) 
							onComplete && onComplete(xhr.responseText)
						else {
							error = jsl.NativeError("ServiceError", [ url, "(code: " + xhr.status + ")" ])
							throw error
						}
					}
				}
				catch(e) {
					jsl.__ni_timer_remove(tid)	
					if(onError)	onError(error)
					else 				jsl.captureError(e, "jsl.__ni_http_request.onChange()")
				}
			}
			
			tid = this.__ni_timer_create(function() {				
				var e 
				
				//xhr.readyState
				//0: open has not been called
				//1: open has been called
				//2: send has been called (waiting the server response)
				//3  some datas has arrived to the client
				//4: transfering completed 
				
				e 		= new jsl.Event
				e.url = url + ""
			
				jsl.throwEvent("beforeServiceTimeOut", e)
				xhr.abort()
				jsl.throwEvent("serviceTimeOut", e)
			}, this.__service_to, 1)
			
			//@sys: Explorer 8 - xhr.onreadystatechange = undefined throw an error -> e.message = 'NotImplemented'
			data 										= data.join("&")											
			xhr.onreadystatechange 	= onChange
			
			try {				
				xhr.open(data ? "POST" : "GET", url, async)
				
				if(data) {
					xhr.setRequestHeader("Content-type"		, "application/x-www-form-urlencoded")
					xhr.setRequestHeader("Content-length"	, data.length)
				}
				
				//@info: no persistent connection				
				xhr.setRequestHeader("Connection", "close")				
				xhr.send(data)	//@sys: Netscape/Flock - if null throw an error
			}
			catch(e) {
				jsl.__ni_timer_remove(tid)	
				error = jsl.NativeError("ServiceError", [ url, "(detail: " + e.message + ")" ])

				if(!onError || onError(error) !== jsl.Event.STOP_DEFAULT)
					throw error
			}
				
			return async ? null : (xhr.responseText && xhr.responseText.length ? xhr.responseText : null)
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_timer_create = function(action, interval, n) {
		try {
			var i, tid, nid, c
			
			//@d[
			if(!arguments.length || arguments.length > 3)	throw jsl.ParamError()
			jsl.validate(action, "f"	, "action")
			
			if(arguments.length >= 2)	jsl.validate(interval	, "i+", "interval")
			
			if(arguments.length === 3) {
				jsl.validate(n, "i++", "n")			
				if(interval === 0 && n !== 1)	throw jsl.ParamError("BadValue:n")
			}
			//@d]
			
			c		= 1 
			i		= interval === 0 ? 1 : (n || Infinity)
      tid = "T" + this.__ni_timers.tid++
			nid	= setTimeout(function() {
				try {
					i--
					action(tid, c++)
					
					//'if test' because we can remove the timer inside the action					
					//jsl.__ni_timers[tid] can be 0? pheraphs
					//jsl.__ni_timers[tid] can be undefined but undefined !== null -> yes
					if(jsl.__ni_timers[tid] != null)
						if(i)	jsl.__ni_timers[tid] = setTimeout(arguments.callee, +interval)
						else	jsl.__ni_timer_remove(tid)
						
				}
				catch(e) {
					jsl.captureError(e, "Timer(tid)", [ tid ])
				}
			}, interval || 0)
      
			this.__ni_timers[tid] = nid
			this.__ni_timers.push(tid)
			return tid
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_timer_remove = function(tid) {
		try {
      var b
			
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(tid, "s+", "tid")
      if(tid.charAt(0) !== "T")  	throw jsl.ParamError("BadId:tid:Timer-Id")
      //@d]
			
			//can be 0? pheraphs
			//undefined !== null -> yes
      if(this.__ni_timers[tid] != null) {
				
				b = true
				clearTimeout(this.__ni_timers[tid])
				delete this.__ni_timers[tid]			
				
				for(var a = this.__ni_timers.length - 1; a >= 0; a--)
					if(this.__ni_timers[a] === tid) {
						this.__ni_timers.splice(a, 1)
						break
					}
			}
							
      return !!b
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_error_capture = function(e, cx, args) {
		try {
			var a, error, childs, panel, title, body, h, rows, node
			
			//@d[
			if(!arguments.length  || arguments.length > 3)	throw jsl.ParamError()//@d]
			
			if(arguments.length === 1)			error = jsl.Error(e)
			else if(arguments.length === 2)	error = jsl.Error(e).trace(cx)
			else														error = jsl.Error(e).trace(cx, args)
			
			for(a = 0; a < this.__ni_timers.length; a++)	
				this.__ni_timer_remove(this.__ni_timers[a])
						
			//-------------------------------------------------------------------------------
			if(document.body) {
				
				if(!this.__vars.errorPanel) {
				
					//live array
					childs = document.body.childNodes				
					while(childs.length) document.body.removeChild(childs[0]) 
					
					body 		= document.body
					title		= document.createElement("div")
					panel		= document.createElement("div")
					
					with(body.style) {
						margin 					= "8px"
						overflow				= "hidden"
						outlineWidth		= "0px"
					}
					
					with(title.style) {
						border 					= "1px solid #3d5070"
						backgroundColor = "#697a97"
						padding					= "5px"
						paddingLeft			= "4px"
						color						= "#FFFFFF"
						fontWeight			= "bold"
					}
					
					//width = auto -> the Gi module change the width to 100% causing a possible panel overflow 
					with(panel.style) {
						border 					= "1px solid #3d5070"
						borderTop				= "0px"
						color						= "#444444"
						fontWeight			= "normal"
						fontSize				= "0.9em"
						overflow				= "scroll"
						width						= "auto"
						backgroundColor = "#EEEEEE"
					}
					
					title.appendChild(document.createTextNode("Liquid"))
					body.appendChild(title)
					body.appendChild(panel)

					//Automatic panel resizing 
					this.__ni_timer_create(function() { 
						var h2
						
						h2 = ((window.innerHeight || document.body.offsetHeight - 4) - title.offsetHeight - 16)					
						
						if(h2 !== h) {
							panel.style.height = h2 + "px" 
							h = h2
						}
					}, 300)

					this.__vars.errorTitle = title
					this.__vars.errorPanel = panel
				}
				else {
					title = this.__vars.errorTitle
					panel = this.__vars.errorPanel
					body	= document.body
				}	
					
				//@sys: Explorer use offsetHeight and the other innerHeight. To adjust the width and height values taking into accout 
				//			the scrollbars subtract (ie 20/other 16) from the width and height 
				h										= ((window.innerHeight || document.body.offsetHeight - 4) - title.offsetHeight - 16)				
				panel.style.height 	= h + "px" 
				rows 								= ["", "", "", "", "An error has occurred in the script:"].concat((e + "").split("\n"))

				for(a = 0; a < rows.length; a++) 
					if(rows[a].slice(0, 9) === "Caused By") {
						rows.splice(a, 0, "", "", "")
						a += 4
				}
				
				for(a = 0; a < rows.length; a++) {
										
					node = document.createElement("div")
					node.appendChild(document.createTextNode(rows[a]))

					with(node.style) {
						borderBottom 	= "1px solid #CCCCCC"
						padding				= "2px"
					
						if(a === 4) {
							backgroundColor	= "#D9D9D9"
							paddingLeft 		= "15px"
							border					= "1px solid #666666"
						}
						else if(rows[a].slice(0, 9) === "Caused By") {
							backgroundColor	= "#D9D9D9"
							paddingLeft 		= "15px"
						}
						else if(rows[a].slice(0, 4) === "  at" || rows[a].replace(/\s+/g, ""))	{
							fontWeight	= "normal"
							paddingLeft	= "55px"
						}
						else {
							backgroundColor	= "#f0d2d8"
							paddingLeft 		= "35px"
						}
					}
					panel.appendChild(node)
				}				
			}
			this.__ni_stdout_error(error)			
			return this
		}
		catch(e2) {
			jsl.throwError(e2, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	;(function() {
		try {
			var l, childs, url, src, search, params, id
			var a, ua, uas, oss, uavId, uav, os, data, prop, idx, jsv, node, head
						
			//-------------------------------------------------------------------------------
			jsl.__ni_timers			= []
			jsl.__ni_timers.tid = 0
			jsl.__ni_liquid_url	= null
			
			jsl.__ni_chrome			= false
			jsl.__ni_explorer		= false
			jsl.__ni_firefox		= false
			jsl.__ni_opera			= false
			jsl.__ni_safari			= false
						
			//1° - System detection: - the order is important (ex: if prism is shifted after netscape, the id is netscape)
			//-------------------------------------------------------------------------------
			uas = [
							{ id: "Fennec"			, string: navigator.userAgent	, subString: "Fennec" 																},
							{ id: "Firefox"			, string: navigator.userAgent	, subString: "Firefox" 																},
							{ id: "Safari"			, string: navigator.vendor		, subString: "Apple"			, versionSearch: "Version" 	},
							{ id: "Chrome"			, string: navigator.userAgent	, subString: "Chrome"																	},
							{ id: "Explorer"		, string: navigator.userAgent	, subString: "MSIE"				, versionSearch: "MSIE" 		},
							{ id: "Opera-mobile", string: navigator.userAgent , subString: "Opera Mobi"	, versionSearch: "Version"  },
							{ id: "Opera"				, string: navigator.userAgent , subString: "Opera" 	 		, versionSearch: "Version"  },
							{ id: "Prism"				, string: navigator.userAgent	, subString: "Prism" 																	},														

							{ id: "AdobeAIR"		, string: navigator.userAgent	, subString: "AdobeAIR"		, versionSearch: "AdobeAIR" }, 
							{ id: "Netscape"		, string: navigator.userAgent	, subString: "Netscape" 															}, //(6+)
							{ id: "Netscape"		, string: navigator.userAgent	, subString: "Mozilla"		, versionSearch: "Mozilla" 	}, //(4-)
							{ id: "Konqueror"		, string: navigator.vendor		, subString: "KDE" 																		},
							{ id: "Mozilla"			, string: navigator.userAgent	, subString: "Geko"				, versionSearch: "rv" 			},
							{ id: "ICab"				, string: navigator.vendor		, subString: "ICab" 																	},
							{ id: "Camino"			, string: navigator.vendor		, subString: "Camino" 																},
							{ id: "OmniWeb"			, string: navigator.userAgent	, subString: "OmniWeb"		, versionSearch: "OmniWeb/" }
						]

			oss	= [
							{ id: "Win"					, string:	navigator.platform	,	subString: "Win"																		},
							{ id: "Mac"					, string:	navigator.platform	,	subString: "Mac"																		},
							{ id: "Linux"				, string:	navigator.platform	,	subString: "linux"																	}
						]

			for(a = 0; a < uas.length && !ua; a++) {

				data = uas[a]
				
				//@sys: data.string can be undefined (ex: opera 10.51)
				if(data.string && data.string.indexOf(data.subString) !== -1) {

					ua 		= data.id
					prop 	= data.versionSearch || data.id
					idx 	= navigator.userAgent.indexOf(prop)

					if(idx != -1)
						uavId = navigator.userAgent.slice(idx + prop.length + 1).match(/[\d\.]+/)[0]
					else {
						idx = navigator.appVersion.indexOf(prop)

						if(idx != -1)
							uavId = navigator.appVersion.slice(idx + prop.length + 1).match(/[\d\.]+/)[0]
					}
          
          if(uavId != null) 
            if(uavId.indexOf(".") !== -1) 
              uav = parseFloat(uavId.slice(0, uavId.indexOf(".") + 1) + uavId.slice(uavId.indexOf(".") + 1).replace(/\./g, "")) 
            else
              uav = parseInt(uavId)          
				}
			}
			
			jsl["__ni_" + ua.toLowerCase()]	= true
			jsl.__ni_ua											= ua
						
			for(a = 0; a < oss.length && !os; a++) {
				data = oss[a]
				if(data.string.indexOf(data.subString) !== -1) 
					os = data.id
			}
			
			//air
			if(ua === "AdobeAIR" && (!parentSandboxBridge || parentSandboxBridge.__signature !== jsl.__signatures["AdobeAIR"]))
				throw jsl.NativeError("AirApiError")
			
			//0° - System type detection
			//-------------------------------------------------------------------------------
			jsl.__stype = ua === "Prism" || ua === "AdobeAIR" ? "desktop" : "web"

			//2° - Liquid url detection
			//-------------------------------------------------------------------------------
			childs 	= document.getElementsByTagName("script")
			l 			= document.location
			
			for(a = 0; a < childs.length; a++) {
				
				//an url can have a query string and/or a fragment id #
				src = childs[a].src.split(/\?|#/)[0]
				
				if(src.slice(-9) === "liquid.js") {
					
					if(url) {
						url = null
						break
					}
					//@sys - Explorer v.8.0.6001.18702/Firefox v.3.5.6 &C
					//ie maintains the value passed at <script>.src but other browser normalize it to absolute url
					url 		= src.replace(/\\/g, "/")
					//document.location is an object not a string
					url 		= jsl.__vars.re.url.test(url) ? url : (l + "").slice(0, (l + "").lastIndexOf("/")) + "/" + url					
					url	 		= url.slice(0, -9) 			
					params	= childs[a].src.split("?")[1]
					params	= params && params.split("#")[0]		
					params 	= jsl.__ni_getParams(params)
					
					if(params.debug)	jsl.setOption("liquid.debug", +params.debug)
					if(params.log)		jsl.setOption("liquid.log"	, params.log)
				}
			}
			
			//ambiguity
			if(url === null)	jsl.__ni_stdout_warn("unable to locate liquid url (found a number of possible matches)")
			else if(!url)			jsl.__ni_stdout_warn("unable to locate liquid url")			

			jsl.__ni_liquid_url = url
			
      //3° - JavaScript version detection
      //-------------------------------------------------------------------------------
      jsl.__vars.tmp.jsv	= -1
      head 								= document.getElementsByTagName("head")[0]
      
      for(a = 1; a < 2; a += 0.1) {
        node            = document.createElement("script")
        node.language   = "Javascript"    			+ a.toFixed(1) //decimal add - arithmetic error: 1.000000000008 
        node.text       = "jsl.__vars.tmp.jsv=" + a.toFixed(1)

        head.appendChild(node)
        head.removeChild(node)
      }
     
      jsv = jsl.__vars.tmp.jsv      
      if(jsv === -1)  jsl.__ni_stdout_warn("unable to detect the JavaScript version supported")

      //4° - Params detection
			//-------------------------------------------------------------------------------
			params = jsl.__ni_getParams(l.search)
			
			//Native infos	
			//-------------------------------------------------------------------------------
			jsl.addInfo("app.url"				   		, (l + "").match(/(.*\/)[^\/]*$/)[1])
			jsl.addInfo("app.fileName"		   	, (l + "").match(/.*\/([^\/#\?]*).*$/)[1])
			jsl.addInfo("app.protocol"		  	, l.protocol.slice(0, l.protocol.length - 1))
			jsl.addInfo("app.hostName"		  	, l.hostname)
			jsl.addInfo("app.hostPort"		  	, l.port)
			
			//pathName can be ex: /Site.html for AdobeAIR in standalone mode
			jsl.addInfo("app.pathName"		  	, l.pathname.match(/(.*?\/)[^\/]+$/)[1])
			jsl.addInfo("app.hash"				  	, l.hash.slice(1))
			jsl.addInfo("app.params"			   	, params	, function(v) { return jsl.Object.copy(v)	})
			
			jsl.addInfo("system.id"						, ua 		|| null)
			jsl.addInfo("system.version"		  , uav		|| null)
			jsl.addInfo("system.versionId"		, uavId	|| null)
			jsl.addInfo("system.os"			  		, os		|| null)
			jsl.addInfo("system.type"					, jsl.__stype)

      jsl.addInfo("javascript.version" 	, jsv)

			//-------------------------------------------------------------------------------
			jsl.__schemes["app"] 		= jsl.getInfo("app.url")
			jsl.__schemes["script"]	= jsl.__schemes["app"]
			jsl.__schemes["liquid"]	= url

			jsl.addOption("script.url", {
				dvalue: jsl.getInfo("app.url"),
				setter: function(url, oldv, id) {
					//@d[
					if(url != null)	jsl.validate(url, "url", id)//@d]
					return this.__schemes["script"] = url ? (url + "/").replace(/\\+/g, "/") : this.getInfo("app.url")
				}
			})
			
			jsl.addOption("liquid.url", {			
				dvalue: url,
				setter: function(url, oldv, id) {													
					//@d[
					if(url != null)	jsl.validate(url, "url", id)//@d]
					return this.__schemes["liquid"] = url ? (url + "/").replace(/\\+/g, "/") : jsl.__ni_liquid_url
				}
			})   
			   
			if(window.addEventListener) {
				window.addEventListener("load"	, jsl.__ni_boot	, false) //@sys: false -> bubbling
				window.addEventListener("unload", jsl.__ni_exit	, false)
			}
			//@sys: Explorer 8.0.6 - typeof attachEvent === "object"
			else if(window.attachEvent) {
				window.attachEvent("onload"		, jsl.__ni_boot)
				window.attachEvent("onunload"	, jsl.__ni_exit)
			}
			else
				throw jsl.NativeError("NotSupported:Listeners")
						
			jsl.__ready = true
		}
		catch(e) {
			jsl.captureError(e, "jsl:native()")
		}
	})()	
		
	}
	
	//V8Cgi system
	//v8cgi -c config [liquid] [app] [params..] (only the first script is executed)
	//-------------------------------------------------------------------------------	
	else {

	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_debug = function(msg) { 
		try {
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]
	
			system.stdout(this.__ni_stdout_header() + "liquid(debug) >> "	+ msg + "\n")	
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_info = function(msg) { 
		try {
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]
	
			system.stdout(this.__ni_stdout_header() + "liquid(info)  >> "	+ msg + "\n")	
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_warn = function(msg) { 
		try {
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]
	
			system.stdout(this.__ni_stdout_header() + "liquid(warn)  >> "	+ msg + "\n")	
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_error = function(msg) { 
		try {
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]
	
			//@sys: v8cgi 0.9: access violation if we pass a not string argument and in the v8cgi.conf 
			//file require.paths.push("F:/v8cgi/lib") point to bad dir
			system.stdout(this.__ni_stdout_header() + "liquid(error) >> "	+ msg + "\n")	
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_stdout_log = function(msg) { 
		try {		
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]
			
			system.stdout(msg + "\n")	
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}	
	//-------------------------------------------------------------------------------
	jsl.__ni_script_load = function(url) { 
		try {
			var f, script, req, res, url2, re
			var d, d0, d1
			
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(url, "url")
			//@d]

			
			//1° - http
			if((/^http:/i).test(url)) {
				
				//no timeout
				//@sys: localhost is not supported
				url2				= url.replace(/^http:\/\/localhost(?=:|\/)/, "http://127.0.0.1")
				req 				= new ClientRequest(url2)
				req.method 	= "GET"
				
				try 			{ res = req.send()																															}
				catch(e) 	{ throw jsl.NativeError("LoadFailed", [ url2, "(detail: " + e.message + ")" ])	}

				if(res.status !== 404 && res.status !== 200)	throw jsl.NativeError("LoadFailed", [ url, "(code: " + res.status + ")" ])
				
				script = res.status === 404 ? null : res.data
			}
			//2° - file
			else if((/^file:/i).test(url)) {			
				//no url validation			
				f = new File(url.slice(0, 8) === "file:///" ? url.slice(8) : url)
				
				if(f.isFile()) {
					f.open("r")
					script = f.read()
					f.close()						
				}
				else 
					script = null				
			}
			//5 ° - not supported
			else if((/^https:/i).test(url))	throw jsl.NativeError("NotSupported:https")			
			//4° - error
			else	throw jsl.ParamError("BadValue:url")
									
			//script is a buffer not a string
			if(script != null) {
				try 			{ d0 = script.toString("ASCII") 			}	catch(e) 	{} 
				try 			{ d1 = script.toString("UTF-8") 			}	catch(e) 	{} 
				
				//@d[
				if(!d0 && !d1)	throw jsl.NativeError("BadCharset:[ ASCII | UTF-8 ]")//@d]										
				d = d0 || d1				
			}
																												
			return d
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_script_execute = function(script) { 
		try {			
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(script, "s", "script")
			//@d]		
												
			try 			{ this.__ni_script_execute.eval(script) }
			catch(e) 	{ throw jsl.ScriptError("BadScript", e) }			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}
	jsl.__ni_script_execute.eval = function(script) { return eval(script) } 
	//-------------------------------------------------------------------------------
	jsl.__ni_http_request = function(url, params) {
		try {
			var Socket, Buffer, s, data, ip, port, method, host, txt, a, readyState, block, tmp, async
			var onChange, onComplete, onError, tid, tid0, pms, code, b, error
		
			//@d[
			if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()
			jsl.validate(url, "url")

			if(arguments.length === 2) {
				if(!jsl.isObject(params))					throw jsl.ParamError("BadType:params:object")
				if(params.__onComplete 	!= null)	jsl.validate(params.__onComplete, "f", "params.__onComplete")
				if(params.__onError 		!= null)	jsl.validate(params.__onError		, "f", "params.__onError")
			}
			//@d]

			Socket 			= require("socket").Socket
			Buffer 			= require("binary").Buffer
			pms					= params || {}
			onComplete	= pms.__onComplete
			onError			= pms.__onError
			
			host				= url.match(/\/\/(.+)\:|\/|$/)[1]
			ip					= host === "localhost" ? "127.0.0.1" : Socket.getAddrInfo(host)			
			port				= url.match(/\:(\d+)/)[1]
			async				= !!onComplete
			readyState	= 0
			data 				= []

			for(a in pms)
				if(a !== "__onComplete" && a !== "__onError")
					data.push(encodeURIComponent(a) + "=" + encodeURIComponent(pms[a])) 
			
			data		= data.join("&")			
			method	= data ? "POST" : "GET"
			txt 		= method + " " + url + " HTTP/1.1\r\n"			
			txt		 += "Host: " + host + "\r\n"   
			txt		 += "Accept-Charset: utf-8\r\n"   
			txt		 += "Accept-Encoding: identity\r\n"   
			txt		 += "Connection: close\r\n"   

			if(data) {
				txt	+= "Content-Length: " + data.length + "\r\n"   
				txt	+= "Content-Type: application/x-www-form-urlencoded\r\n"   			
				txt += data + "\r\n"
			}
			
			txt += "\r\n"
																
			onChange = function() {
				try {
					var e, content, error, b
				
					try 			{ block = s.receive(4096)																												}
					catch(e) 	{	throw jsl.NativeError("ServiceError", [ url, "detail: " + e.message + ")" ])	}
					
					if(block.length) {										
						tmp 	= new Buffer(data.length + block.length)
						tmp.copyFrom(data)
						tmp.copyFrom(block, 0, data.length)
						data 				= tmp
						readyState 	= 3
					}					
					else {
						jsl.__ni_timer_remove(tid0)
						tid && jsl.__ni_timer_remove(tid)
						s.close()					
						readyState 	= 4
						
						//if the data are not in utf-8 for example if is loaded a static file (jsl.js with '°' charcaters): 
						//Transcoding error at source byte 75553 - an invalid multibyte sequence has been encountered in the input
						try				{ data = data.toString("utf-8")															}			
						catch(e) 	{ throw jsl.NativeError("UTF8EncodingError:http(data)", e)	}
						
						code = data.match(/\s(\d+)\s/)							
						code = code ? parseInt(code[1]) : 0						
						if(code !== 200)	throw jsl.NativeError("ServiceError", [ url, "(code: " + code + ")" ])
												
						content			= data = data.match(/\r\n\r\n([\s\S]*)$/)[1]
						onComplete && onComplete(content)
					}
				}
				catch(e) {
					tid && jsl.__ni_timer_remove(tid)
					if(readyState < 4) s.close()
					
					error	= jsl.Error(e) 
					if(onError) onError(error)
					else				jsl.captureError(error, "jsl.__ni_http_request.onChange()")
				}
			}

			tid0 = this.__ni_timer_create(function() {				
				var e 
				
				e 		= new jsl.Event
				e.url	= url + "" 
			
				jsl.throwEvent("beforeServiceTimeOut", e)
				s.close()
				jsl.throwEvent("serviceTimeOut", e)

			}, this.__service_to, 1)
			
			data = new Buffer(0)	

			try {
				s = new Socket(Socket.PF_INET, Socket.SOCK_STREAM, Socket.IPPROTO_TCP)
				s.connect(ip, port)
				readyState = 1
				s.send(txt)
				readyState = 2				
			}
			catch(e) {
				jsl.__ni_timer_remove(tid0)
				error = jsl.NativeError("ServiceError", [ url, "(detail: " + e.message + ")" ]) 

				if(!onError || onError(error) !== jsl.Event.STOP_DEFAULT)
					throw error
			}

			if(!async) {
				do {
					onChange()		
				} while(block.length)																
			}
			else 
				tid = this.__ni_timer_create(onChange, 50)				
								
			return data
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_timer_create = function(action, interval, n) {
		try {
			var i, tid, data, c
			
			//@d[
			if(!arguments.length || arguments.length > 3)	throw jsl.ParamError()
			jsl.validate(action, "f"	, "action")
			
			if(arguments.length >= 2)	jsl.validate(interval	, "i+", "interval")
			
			if(arguments.length === 3) {
				jsl.validate(n	, "i++", "n")			
				if(interval === 0 && n !== 1)	throw jsl.ParamError("BadValue:n")
			}
			//@d]

			c			= 1
			i			= interval === 0 ? 1 : (n || Infinity)
      tid   = "T" + this.__ni_timers.tid++
			data	= {				
				tid:			tid,
				interval:	interval || 0,
				time:			new Date,
				action: 	function() { 
					try {
						i--
						action(tid, c++)

						//'if test' because we can remove the timer inside the action					
						if(jsl.__ni_timers[tid] && !i)
							jsl.__ni_timer_remove(tid)
					}
					catch(e) {
						jsl.captureError(e, "Timer(tid)", [ tid ])
					}
				}
			}
			      
			this.__ni_timers[tid] = data
			this.__ni_timers.push(data)
			return tid
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_timer_remove = function(tid) {
		try {
      var b
			
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(tid, "s+", "tid")
      if(tid.charAt(0) !== "T")  	throw jsl.ParamError("BadId:tid:Timer-Id")
      //@d]
			
      if(this.__ni_timers[tid]) {
								
				delete this.__ni_timers[tid]			

				for(var a = this.__ni_timers.length - 1; a >= 0; a--)
					if(this.__ni_timers[a].tid === tid) {
						this.__ni_timers.splice(a, 1)
						b = true
						break
					}
			}
							
      return !!b
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_xml_parse = function(source, callback) {	
		try {
			var DOM, parser, node
			
			//@d[		
			if(arguments.length !== 2)	throw jsl.ParamError()
			jsl.validate(source		, "s+", "source")
			jsl.validate(callback	, "f"	, "callback")			
			//@d]

			DOM 		= require("dom")
			parser 	= new DOM.DOMParser()
			node 		= parser.parseFromString(source);
			
			arguments.callee.walk(node, callback)						
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}	
	//-------------------------------------------------------------------------------
	jsl.__ni_xml_parse.walk = function(node, callback) {	
		try {			
			
			callback(node.nodeName, node.nodeType, node.nodeValue, node.attributes)
			
			for(var a = 0, l = node.childNodes.length; a < l; a++)
				arguments.callee(node.childNodes[a], callback)						
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}	
	}		
	//-------------------------------------------------------------------------------
	jsl.__ni_error_capture = function(e, cx, args) {	
		try {
			var a, error
			
			//@d[		
			if(!arguments.length  || arguments.length > 3)	throw jsl.ParamError()//@d]
			
			if(arguments.length === 1)			error = jsl.Error(e)
			else if(arguments.length === 2)	error = jsl.Error(e).trace(cx)
			else														error = jsl.Error(e).trace(cx, args)
			
			for(a = 0; a < this.__ni_timers.length; a++)	
				this.__ni_timer_remove(this.__ni_timers[a].tid)
			
			this.__ni_stdout_error(error)		
			return this
		}
		catch(e2) {
			jsl.throwError(e2, this, arguments)
		}	
	}
	//-------------------------------------------------------------------------------
	;(function() {	
		try {
			var args, uav, uavId, idx, os, url, fname, pname, app, fapp, path, script, host, params
			
			args = system.args			
			if(args.length === 1) 						throw jsl.ParamError("NotDefined:app")
			if(!(/liquid.js$/).test(args[0]))	throw jsl.ParamError("BadCliArgs")

			jsl.__ni_timers			= []
			jsl.__ni_timers.tid = 0
			jsl.__ni_liquid_url	= null
			
			//@sys: if we require/include a not existent path the system freeze for a lot of seconds
			//			before throw an errore on the stdout. If the lib is already loaded an error is not throwed 
			//			the module can be not found if the config file is bad configured and this ca throw an error
			//			before this error the timers structure must be initialized or infinite loop in captureError
			include("fs", "http")
						
			uavId = v8cgi.version
			idx		= uavId.indexOf(".")

      if(idx !== -1) 	uav = parseFloat(uavId.slice(0, idx + 1) + uavId.slice(idx + 1).replace(/\./g, ""))
      else        		uav = parseInt(uavId)          
			
			os = system.env.OS
			if(os.search(/win/i) 				!== -1)	os = "Windows"
			else if(os.search(/mac/i) 	!== -1) os = "Mac"
			else if(os.search(/linux/i) !== -1)	os = "Linux"
			
			path	= args[1].replace(/\\/g, "/").replace(/\s+/g, "")			
			fname	= path.slice(path.lastIndexOf("/") + 1).match(/[^\?#]+/)[0] 					
			
			//1° - http url
			if((/^http:/i).test(path)) {
			
				pname	= path.match(/^http:\/\/(?:\w+:?\w*@)?(?:\S+)(?::[0-9]+)?(\.+)/)[1]
				pname	= pname	.slice(0, pname.lastIndexOf("/")	+ 1) 					
				url		= path	.slice(0, path.lastIndexOf("/")		+ 1)
				host	= ""
			}
			//2° - file url
			else {

				if(!fname)	throw jsl.ParamError("BadValue:app")

				pname	= path.slice(0, path.lastIndexOf("/")	+ 1) 					
				url		= (system.getcwd() + "/").replace(/\\+/g, "/") + pname  											
				fapp	= new File(url + fname)
	
				if(!fapp.isFile())	{
					url		= pname
					fapp 	= new File(url + fname)				
					if(!fapp.isFile())	throw jsl.NativeError("BadResource"	, [ url + fname ])
				}
				url = "file:///" + (url.charAt(0) === "/" ? url.slice(1) : url)
				host	= "127.0.0.1" 
			}
									
			jsl.__ni_liquid_url = ("file:///" + args[0].replace(/\\/g, "/").slice(0, -9)).replace(/\/\/\/\//, "///")
			params							= path.match(/\?(.+)/)
			params 							= jsl.__ni_getParams(params && params[1])
			
			if(params.debug)	jsl.setOption("liquid.debug", +params.debug)
			if(params.log)		jsl.setOption("liquid.log"	, params.log)
								
			//Native infos	
			//-------------------------------------------------------------------------------
			jsl.addInfo("app.url"				   		, url)
			jsl.addInfo("app.fileName"		   	, fname)
			jsl.addInfo("app.protocol"		  	, url.slice(0, url.indexOf(":")))
			jsl.addInfo("app.hostName"		  	, "localhost")
			jsl.addInfo("app.hostPort"		  	, null)
			jsl.addInfo("app.pathName"		  	, pname)
			jsl.addInfo("app.hash"				  	, "")
			jsl.addInfo("app.params"			   	, args.slice(2)	, function(v) { return jsl.Object.copy(v)	})

			jsl.addInfo("system.id"						, "V8Cgi")
			jsl.addInfo("system.version"		  , uav)
			jsl.addInfo("system.versionId"		, uavId)
			jsl.addInfo("system.type"					, "cli")
			jsl.addInfo("system.os"			  		, os || null)

      jsl.addInfo("javascript.version" 	, 1.9)

			//-------------------------------------------------------------------------------
			jsl.__schemes["app"] 		= url
			jsl.__schemes["script"]	= jsl.__schemes["app"]
			jsl.__schemes["liquid"]	= jsl.__ni_liquid_url
			
			jsl.addOption("script.url", {
				dvalue: jsl.getInfo("app.url"),
				setter: function(url, oldv, id) {
					//@d[
					if(url != null)	jsl.validate(url, "url", id)//@d]
					return this.__schemes["script"] = url ? (url + "/").replace(/\\+/g, "/") : this.getInfo("app.url")
				}
			})

			jsl.addOption("liquid.url", {			
				dvalue: jsl.__ni_liquid_url,
				setter: function(url, oldv, id) {								
					//@d[
					if(url != null)	jsl.validate(url, "url", id)//@d]
					return this.__schemes["liquid"] = url ? (url + "/").replace(/\\+/g, "/") : jsl.__ni_liquid_url
				}
			})   
			
			onexit(jsl.__ni_exit)
			script 			=	jsl.__ni_script_load(url + fname)		
			jsl.__ready = true
			
			//application
			try 			{	jsl.__ni_script_execute(script) 																				}
			catch(e) 	{ throw (e instanceof jsl.ScriptError ? e.setScriptName(url + fname) : e)	}
		}
		catch(e) {
			jsl.captureError(e, "jsl:native()")
		}
	})()

	//-------------------------------------------------------------------------------
	;(function() {
		var a, timers
	
		jsl.__ni_boot()
		
		while(jsl.__ni_timers.length) {
			
			system.usleep(15000)

			//@info:buffered otherwise infinite loop into for if the action creates new timer
			timers = jsl.__ni_timers.slice()
	
			//@info: a timer created before another timer with same delay must executed before
			timers.sort(function(t1, t2) { return t1.tid < t2.tid })
			
			for(a = 0; a < timers.length; a++) 
				if(new Date - timers[a].time >= timers[a].interval) {
					timers[a].action()
					timers[a].time = new Date
				}
		}
	})()
	}
